/**
 * @file xmlConfig.cpp
 * @brief XML配置文件源文件
 * @author zhangpeihao
 */
#include <zsystem/core/common/log.h>
#include <zsystem/core/xml/xmlConfig.h>
#include <map>

//char zsystem::xmlConfig::_usage[MAX_USAGE_LEN] = "-h                        print this help and exit.\n"
//                                                 "-config=<file>            config file name.\n";

const Z_BOOL 
zsystem::xmlConfig::open(const char* filePath, xmlGetOpt* opt)
{
  xmlNode root(Z_NULL);
  std::string strFilePath;

  if (opt != Z_NULL)
  {
    if (opt->getRootNode(root))
    {
      xmlNode node(Z_NULL);
      if (opt->getChildNodeByPath(root, "config", node))
      {
        opt->read(node, strFilePath);
      }
      else
      {
        LOG(WARNING) << "Load config file setting from command args failed!";
        return Z_FALSE;
      }
    }
    else
    {
      LOG(WARNING) << "Load command args failed!";
      return Z_FALSE;
    }
  }

  if (strFilePath.empty())
  {
    if (filePath != Z_NULL && strnlen(filePath, 1024) > 0)
    {
      strFilePath = filePath;
    }
    else
    {
      LOG(WARNING) << "Neither settings or command args have config file path!";
      return Z_FALSE;
    }
  }

  if (!xmlFile::open(strFilePath.c_str()))
  {
    LOG(WARNING) << "Open config file[" << strFilePath << "] failed!";
    return Z_FALSE;
  }
  else
  {
    if (root != Z_NULL)
    {
      xmlNode thisRoot;
      if (!this->getRootNode(thisRoot))
      {
        LOG(WARNING) << "Load root node of config file failed!";
        return Z_FALSE;
      }
      xmlNode node = root->FirstChildElement();
      const char* nodeValue(Z_NULL);
      while (Z_NULL != node)
      {
        if (!this->read(node, nodeValue))
        {
          // 读取失败
          LOG(WARNING) << "Read command args[" << node->Value() << "] failed!";
          return Z_FALSE;
        }
        xmlNode childNode = this->getChildNodeByPath(thisRoot, node->Value());
        if (Z_NULL != childNode)
        {
          // Exist Node
          // Get first text node
          TiXmlText* text(Z_NULL);
          TiXmlNode* clindNodeItem = childNode->FirstChild();
          while(clindNodeItem != Z_NULL && text == Z_NULL)
          {
            text = clindNodeItem->ToText();
            clindNodeItem = clindNodeItem->NextSibling();
          }
          if ( text == Z_NULL)
          {
            // no text item
            text = Z_NEW(TiXmlText)(nodeValue);
            childNode->InsertEndChild(*text);
            Z_SAFE_DELETE(text, ~TiXmlText);
          }
          else
          {
            text->SetValue(nodeValue);
          }
        }
        else
        {
          // New node
          childNode = Z_NEW(TiXmlElement)(node->Value());
          TiXmlText* text = Z_NEW(TiXmlText)(nodeValue);
          childNode->InsertEndChild(*text);
          Z_SAFE_DELETE(text, ~TiXmlText);
          thisRoot->InsertEndChild(*childNode);
          Z_SAFE_DELETE(childNode, ~TiXmlElement);
        }

        node = node->NextSiblingElement();
      }
    }
    return Z_TRUE;
  }
  return Z_TRUE;
}

